
#ifndef _INCLUDE_COMMONDEF_H_
#define _INCLUDE_COMMONDEF_H_

#include <ntddk.h>
#include <wdm.h>
#include <ntdef.h>

#if defined(__cplusplus)
# define RT_C_DECLS_BEGIN extern "C" {
# define RT_C_DECLS_END   }
#else
# define RT_C_DECLS_BEGIN
# define RT_C_DECLS_END
#endif

#define IN_RING0 1

#if defined(_ARM64_)
typedef UINT64 RTR3PTR;
typedef void *RTR0PTR;
#else
typedef UINT32 RTR3PTR;
typedef void *RTR0PTR;
#endif

struct RTR0MEMOBJINTERNAL;
/** Ring-0 memory object handle. */
typedef RTR0MEMOBJINTERNAL *RTR0MEMOBJ;
/** Pointer to a Ring-0 memory object handle. */
typedef RTR0MEMOBJ *PRTR0MEMOBJ;
/** Nil ring-0 memory object handle. */
#define NIL_RTR0MEMOBJ 0

typedef UINT64 *RTR0UINTPTR;
/** Process ring-0 handle. */
typedef RTR0UINTPTR                                 RTR0PROCESS;
/** Pointer to a ring-0 process handle. */
typedef RTR0PROCESS *PRTR0PROCESS;
/** Nil ring-0 process handle. */
#define NIL_RTR0PROCESS ((RTR0PROCESS)~0ULL)

/** Host Physical Memory Address. */
typedef UINT64          RTHCPHYS;
/** Pointer to Host Physical Memory Address. */
typedef RTHCPHYS        *PRTHCPHYS;
/** Pointer to const Host Physical Memory Address. */
typedef const RTHCPHYS  *PCRTHCPHYS;
/** @def NIL_RTHCPHYS
 * NIL HC Physical Address.
 * NIL_RTHCPHYS is used to signal an invalid physical address, similar
 * to the NULL pointer.
 */
#define NIL_RTHCPHYS            (~(RTHCPHYS)0)
 /** Max RTHCPHYS value. */
#define RTHCPHYS_MAX            UINT64_MAX

/** Guest Physical Memory Address.*/
typedef UINT64                RTGCPHYS;
typedef RTGCPHYS RTCCPHYS;

/** Pointer to Current Context Physical Memory Address. */
typedef RTCCPHYS        *PRTCCPHYS;
/** Pointer to const Current Context Physical Memory Address. */
typedef const RTCCPHYS  *PCRTCCPHYS;

/** Process identifier. */
typedef UINT32                                    RTPROCESS;
/** Pointer to a process identifier. */
typedef RTPROCESS                                *PRTPROCESS;
/** Nil process identifier. */
#define NIL_RTPROCESS                             (~(RTPROCESS)0)

#if defined(_ARM64_)
typedef UINT64 RTR3PTR;
typedef void            *RTR0PTR;
#else
typedef UINT32 RTR3PTR;
typedef void            *RTR0PTR;
#endif

#define NIL_RTR3PTR            ((RTR3PTR)0)

#define RT_ALIGN_T(u, uAlignment, type)         ( ((type)(u) + ((uAlignment) - 1)) & ~(type)((uAlignment) - 1) )
#define RT_ALIGN_32(u32, uAlignment)            RT_ALIGN_T(u32, uAlignment, uint32_t)
#define RT_ALIGN_64(u64, uAlignment)            RT_ALIGN_T(u64, uAlignment, uint64_t)
#define RT_ALIGN_Z(cb, uAlignment)              RT_ALIGN_T(cb, uAlignment, size_t)
#define RT_ALIGN_P(pv, uAlignment)              RT_ALIGN_PT(pv, uAlignment, void *)
#define RT_ALIGN_PT(u, uAlignment, CastType)    ( (CastType)RT_ALIGN_T(u, uAlignment, uintptr_t) )

#define RT_SRC_POS_DECL    const char *pszFile, unsigned iLine, const char *pszFunction

#define PAGE_OFFSET_MASK    0xfff
#define X86_PAGE_4K_BASE_MASK 0xfffffffffffff000ULL

#define _1K 1024
#define _8K (_1K * 8)
#define _128K (_1K * 128)
#define _1M (_1K * _1K)
#define _2M (_1M * 2)
#define _4M (_1M * 4)
#define _1G (_1M * 1024LL)
#define _2G (_1G * 2LL)
#define _4G (_1G * 4LL)
/** This value(5400*800=4320000) is the maximum physical memory that can be applied for in the window zoom-in scenario.
 * & 4-byte alignment
 */
#define _TEMP_LIMIT_MEM (4321280)

#define VINF_SUCCESS                        0
#define VINF_ALREADY_INITIALIZED            28
#define VERR_INVALID_PARAMETER              (-2)
#define VERR_INVALID_HANDLE                 (-4)
#define VERR_INVALID_POINTER                (-6)
#define VERR_NO_MEMORY                      (-8)
#define VERR_NOT_IMPLEMENTED                (-12)
#define VERR_NO_PAGE_MEMORY                 (-27)
#define VERR_INVALID_FUNCTION               (-36)
#define VERR_NOT_SUPPORTED                  (-37)
#define VERR_TOO_MUCH_DATA                  (-42)
#define VERR_OUT_OF_RANGE                   (-54)
#define VERR_MEMORY_BUSY                    (-67)
#define VERR_NO_LOW_MEMORY                  (-72)
#define VERR_MAP_FAILED                     (-75)
#define VERR_NOT_FOUND                      (-78)
#define VERR_INVALID_STATE                  (-79)
#define VERR_OUT_OF_RESOURCES               (-80)
#define VERR_ALREADY_EXISTS                 (-105)
#define VERR_INTERNAL_ERROR                 (-225)

#define RT_SUCCESS_NP(rc)   ((int)(rc) >= VINF_SUCCESS)
#define RT_SUCCESS(rc)      (((rc) == 0))
#define RT_FAILURE(rc)      ((!RT_SUCCESS_NP(rc)))
#define RT_BOOL(Value)      (!!(Value))

#define RT_MIN(a, b) ((a) < (b) ? (a) : (b))
#define RT_MAX(a, b) ((a) > (b) ? (a) : (b))

#define RT_ELEMENTS(aArray) (sizeof(aArray) / sizeof((aArray)[0]))

#  define RT_LIKELY(expr)       (expr)
#  define RT_UNLIKELY(expr)     (expr)

#define RT_NOREF(...) (void)(##__VA_ARGS__)
#define DECLINLINE(type) static inline type
#define AssertPtrReturn(pv, rcRet) do { if (pv) {} else return(rcRet); } while(0)
#define AssertReturn(expr, rc) \
    do { \
        if ((!!(expr))) \
        { /* likely */ } \
        else \
            return (rc); \
    } while (0)

#define AssertMsgReturn(expr, msg, rc) \
    do { \
        if ((!!(expr))) \
        { /* likely */ } \
        else \
            return (rc); \
    } while (0)

#define AssertReturnStmt(expr, stmt, rc) \
    do { \
        if (!!(expr)) \
        { /* likely */ } \
        else \
        { \
            stmt; \
            return (rc); \
        } \
    } while (0)

#define AssertReturnVoid(expr) \
    do { \
        if (!!(expr)) \
        { /* likely */ } \
        else \
            return; \
    } while (0)

#define AssertReturnVoidStmt(expr, stmt) \
    do { \
        if (!!(expr)) \
        { /* likely */ } \
        else \
        { \
            stmt; \
            return; \
        } \
    } while (0)

#define AssertFailedReturnStmt(stmt, rc)  \
    do { \
        stmt; \
        return (rc); \
    } while (0)

#define AssertBreakStmt(expr, stmt) \
    if (!!(expr)) \
    { /* likely */ } \
    else if (1) \
    { \
        stmt; \
        break; \
    } else do {} while (0)

#define AssertMsgRCReturn(rc, msg, rcRet) \
    do { AssertMsgReturn(RT_SUCCESS_NP(rc), msg, rcRet); } while (0)

#define AssertRCReturn(rc, rcRet)   AssertMsgRCReturn(rc, ("%Rra\n", (rc)), rcRet)

# define AssertFailed() do { } while (0)
# define Assert(expr)   do { } while (0)

#ifndef MAX_UINT64
#define MAX_UINT64 0xffffffffffffffffui64
#endif
#ifndef MAX_UINT32
#define MAX_UINT32 0xffffffffui32
#endif
#ifndef MAX_UINT16
#define MAX_UINT16 0xffffui16
#endif

#define RT_ALIGN_T(u, uAlignment, type)        ( ((type)(u) + ((uAlignment) - 1)) & ~(type)((uAlignment) - 1) )
#define RT_UOFFSETOF_DYN(type, memberarray)    ( (uintptr_t)&( ((type *)(void *)0)->memberarray) )

/** I/O Port. */
typedef UINT16    RTIOPORT;

typedef UINT64    PA;
typedef UINT32    PPN;
typedef UINT64    PPN64;

 /**
  * The size of a rectangle.
  */
typedef struct RTRECTSIZE
{
    /** The width (along the x-axis). */
    UINT32    cx;
    /** The height (along the y-axis). */
    UINT32    cy;
} RTRECTSIZE, *PRTRECTSIZE;
/** Pointer to a const rectangle size. */
typedef const RTRECTSIZE *PCRTRECTSIZE;

// In high memory pressure, offset func might get wrong ret
#define RT_OFFSETOF(type, member)       ( (uintptr_t)&( ((type *)(void *)0)->member) )
#define RT_UOFFSETOF(type, member)      ( (uintptr_t)&( ((type *)(void *)0)->member) )

/** @def RT_SIZEOFMEMB
 * Get the size of a structure member.
 *
 * @returns size of the structure member.
 * @param   type    Structure type.
 * @param   member  Member.
 */
#define RT_SIZEOFMEMB(type, member) (sizeof(((type *)(void *)0)->member))

#define RT_FROM_MEMBER(pMem, Type, Member)      ( (Type *) ((UINT8 *)(void *)(pMem) - RT_UOFFSETOF(Type, Member)) )
#define RT_FROM_CPP_MEMBER(pMem, Type, Member) RT_FROM_MEMBER(pMem, Type, Member)

#define RT_FALL_THRU()  (void)0

#define RT_BZERO(pv, cb)    do { memset((pv), 0, cb); } while (0)
#define RT_ZERO(Obj)        RT_BZERO(&(Obj), sizeof(Obj))

DECLINLINE(INT64) SystemTime()
{
    LARGE_INTEGER t{0, 0};
    KeQuerySystemTime(&t);
    return ((INT64)t.HighPart << 32) + t.LowPart;
}

/** RTR0MEMOBJ::u32Magic. (Masakazu Katsura) */
#define RTR0MEMOBJ_MAGIC                UINT32_C(0x19611210)

#define RTDECL(T) T
#define RTCALL
#define DECLCALLBACK(type) type
#define RT_FAR
#define RT_FLEXIBLE_ARRAY
#define RT_NOREF(t) (void)t
#define NOREF(t) RT_NOREF(t)
#define RT_NOREF1(t) (void)t

#define SVGA_MEMTAG 'AGVS'

#endif //~_INCLUDE_COMMONDEF_H_
